/*
 * Copyright 2024 The JA-SIG Collaborative. All rights reserved.
 * distributed with thi file and available online at
 */
package com.lap.permission.service.impl;

import com.lap.framework.dto.page.Page;
import com.lap.framework.dto.page.PageDTO;
import com.lap.framework.exception.ExceptionHandler;
import com.lap.permission.cachekey.MenuKey;
import com.lap.permission.cachekey.ResourceKey;
import com.lap.permission.cachekey.UserKey;
import com.lap.permission.convert.Convert;
import com.lap.permission.dal.MenuDAO;
import com.lap.permission.dal.RoleDAO;
import com.lap.permission.dal.UserDAO;
import com.lap.permission.domain.entity.Role;
import com.lap.permission.domain.entity.User;
import com.lap.permission.domain.pojo.UserState;
import com.lap.permission.dto.query.UserQuery;
import com.lap.permission.dto.response.UserDTO;
import com.lap.permission.dto.response.UserInfoDTO;
import com.lap.permission.manager.UserManager;
import com.lap.permission.service.UserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@RequiredArgsConstructor
@Service
public class UserServiceImpl implements UserService {

    private final UserManager userManager;

    private final UserDAO userDAO;

    private final RoleDAO roleDAO;

    private final MenuDAO menuDAO;

    private final Convert convert;

    @Override
    public PageDTO<List<UserDTO>> queryPage(UserQuery query) {
        long count = userDAO.countPage(query);
        if (count == 0) {
            return Page.ok(count);
        }
        List<User> dataList = userDAO.queryPage(query);
        List<UserDTO> result = dataList.stream()
                .map(item -> {
                    UserDTO dto = convert.toUserDto(item);
                    dto.setPassword(null);
                    return dto;
                }).toList();

        return Page.ok(result, count);
    }

    @Override
    public PageDTO<List<User>> querySelect(UserQuery query) {
        long count = userDAO.countSelect(query);
        if (count == 0) {
            return Page.ok(count);
        }
        return Page.ok(userDAO.querySelect(query), count);
    }

    @Cacheable(value = UserKey.USER, key = "#userId", unless = "#result==null")
    @Override
    public User queryById(Integer userId) {
        return userDAO.queryById(userId);
    }

    @Override
    public User queryByUsername(String username) {
        return userDAO.queryByUsername(username);
    }

    @Cacheable(value = UserKey.USER_INFO, key = "#userId", unless = "#result==null")
    @Override
    public UserInfoDTO queryUserInfo(Integer userId) {
        User user = userDAO.queryById(userId);
        if (Objects.isNull(user))
            throw ExceptionHandler.newBiz("10102");

        List<Role> roles = roleDAO.queryByUserId(userId);

        List<String> permList = null;
        if (CollectionUtils.isNotEmpty(roles)) {
            List<Integer> roleIds = roles.stream().map(Role::getId).toList();
            permList = menuDAO.queryPermByRoleIds(roleIds);
        }

        UserInfoDTO dto = new UserInfoDTO();
        dto.setUserId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setPhoto("https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500");
        dto.setTime(new Date());
        dto.setRoles(convert.toRoleDto(roles));
        dto.setAuthBtnList(permList);
        return dto;
    }

    @Override
    public List<User> queryByIds(List<Integer> ids) {
        return userDAO.queryByIds(ids);
    }

    @Override
    public Integer insertUser(User user) {
        userDAO.insertUser(user);
        return user.getId();
    }

    @CacheEvict(value = {UserKey.USER_INFO, UserKey.USER}, key = "#user.id")
    @Override
    public int updateUser(User user) {
        return userDAO.updateUser(user);
    }

    @Override
    public int updateState(UserState userState) {
        return userDAO.updateState(userState);
    }

    @CacheEvict(value = {UserKey.USER_INFO, MenuKey.MENU_TREE_USER, ResourceKey.RESOURCE_USER}, key = "#userId")
    @Override
    public int deleteById(Integer userId) {
        return userManager.deleteById(userId);
    }

}
